package com.bizmda.bizsip.source.netty;
import com.bizmda.bizsip.common.BizConstant;
import com.bizmda.bizsip.common.BizException;
import com.bizmda.bizsip.common.BizResultEnum;
import com.bizmda.bizsip.source.api.SourceBeanInterface;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;

/**
 * @author 史正烨
 */
@Slf4j
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
    private SourceBeanInterface sourceService;
    public NettyServerHandler(SourceBeanInterface sourceService) {
        super();
        this.sourceService = sourceService;
    }

    /**
     * 客户端连接会触发
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.debug("Channel active......");
    }

    /**
     * 客户端发消息会触发
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //TODO:TCP传输过程中的分包拆包问题有待后期解决，建议采用添加不同解码器的方式来处理
        log.debug("服务器收到消息: {}", msg.toString());
        byte[] outBytes = null;
        try {
            byte[] inBytes;
            if (msg instanceof ByteBuf) {
                ByteBuf byteBuf = (ByteBuf)msg;
                inBytes = byteBuf.array();
            }
            else if (msg instanceof byte[]) {
                inBytes = (byte[])msg;
            }
            else if (msg instanceof String) {
                inBytes = ((String)msg).getBytes(BizConstant.DEFAULT_CHARSET_NAME);
            }
            else {
                throw new BizException(BizResultEnum.CONNECTOR_TCP_READ_TYPE_ERROR);
            }
            outBytes = (byte[])this.sourceService.process(inBytes);
        } catch (BizException e) {
            log.error("客户端适配器执行出错!",e);
            ctx.disconnect();
            return;
        }
        ctx.write(new String(outBytes,BizConstant.DEFAULT_CHARSET_NAME));
        ctx.flush();
        ctx.close();
    }

    /**
     * 发生异常触发
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}
